<?php

class View
{
    /**
     * @var array
     */
    static protected $_paths = array(
        NUO_MODULE_PATH,
        NUO_APP_PATH
    );

    /**
     * @var Nuo_View
     */
    static protected $_view = null;

    /**
     * parser object.
     */
    static protected $_parser = null;

    /**
     * @return view object
     */
    static public function getInstance()
    {
        if (null == self::$_view)
        {
            self::$_view = new self;
        }
        return self::$_view;
    }

    /**
     * set parser engine
     * @param Nuo_View_Parser $parser
     * @return void
     */
    static public function setParser(Nuo_View_Parser $parser)
    {
        self::$_parser = $parser;
    }

    /**
     * get parser
     * @return Nuo_View_Parser
     */
    static public function getParser()
    {
        if (null == self::$_parser)
        {
            require_once 'Nuo/View/Parser.php';
            self::$_parser = new Nuo_View_Parser;
        }
        return self::$_parser;
    }

    /**
     * find scripts in current search path
     * @param string $script
     * @param bool $include search path enabled?
     */
    static public function findScript($script, $include = 1)
    {
        if ($include)
        {
            foreach (self::$_paths as $path)
            {
                if (file_exists($file = $path . $script))
                {
                    return $file;
                }
            }
        }
        else
        if (file_exists($script))
        {
            return $script;
        }
        return null;
    }

    /**
     * @param array $scripts
     * @param bool $include
     * @param array $paths
     * @return string|null
     */
    static public function findScripts($scripts, $include = 1, $paths = null)
    {
        foreach ($scripts as $script)
        {
            if (null != ($script = self::findScript($script)))
            {
                return $script;
            }
        }
        return null;
    }

    /**
     * @param array $data
     * @param string|array $scripts
     * @param bool $include search include path
     * @throws Nuo_Exception
     */
    static public function render($data, $scripts, $include = 1, $paths = null)
    {
        ob_start();

        $script = is_string($scripts) ? self::findScript($scripts, $include, $paths) : self::findScript($scripts, $include, $paths);

        if (!$script)
        {
            throw new Nuo_Exception(sprintf("script [%s] not found in paths [%s]", implode(PATH_SEPARATOR, (array)$scripts), implode(PATH_SEPARATOR, self::$_paths)));
        }

        /**
         * start buffer
         */
        extract((array)$data, EXTR_SKIP);

        $view = self::getInstance();

        include $script;
        /**
         * get clean
         */
        return ob_get_clean();
    }

    /**
     * add path to scripts
     * @param string $path
     * @return void
     * @throws Nuo_Exception
     */
    static public function addPath($path)
    {
        if (realpath($path))
        {
            self::$_paths = array_unshift(self::$_paths, $path);
        }
        else
        {
            throw new Nuo_Exception("$path is not found");
        }
    }

    /**
     * render a layoutname
     * @param string layout name
     * @return string xhthml string
     */
    static public function renderLayout($request, $regions = array('header','content','footer'))
    {

        $fullActionName = $request -> getFullActionName();

        $api = Nuo::getApi('core@layout');

        $side = strpos($fullActionName, '@admin') ? 'admin' : 'front';

        $siteId = Nuo::getSiteId();
        $xhtml = array();
        $parser = self::getParser();

        foreach ($regions as $region)
        {
            list($areas, $layout) = $api -> getStructure($region, $fullActionName, $side, $site_id);
            $xhtml[] = $parser -> renderRegion($areas, $layout);
        }
        
        /**
         * process area to get content of layouts.
         */
        return implode(PHP_EOL, $xhtml);
    }

}
